/*
项目性能测试
*/
#include <vector>
#include <thread>
#include <chrono>
#include "../Logs/Uselog.h"

// 需要传入：
// 1. logger_name：日志器名称
// 2. thread_count：线程数量
// 3. msg_count：打印的信息数量
// 4. msg_len：打印的信息长度
void Bench(const std::string &logger_name, size_t thread_count, size_t msg_count, size_t msg_len)
{
    // 1. 使用前，先获取日志对象
    LogModule::Logger::ptr logger = LogModule::GetLogger(logger_name);
    if (logger.get() == nullptr)
        return;
    // 2. 测试日志功能，肯定需要日志打印的数据
    std::string msg(msg_len - 1, 'A'); // 增加一个换行
    // 3. 创建指定数量的线程
    std::vector<std::thread> threads;
    std::vector<double> cost_array(thread_count);
    // 创建3个线程，一百万条数据，每个线程应该写入三十三万条数据
    // 而不是一个线程一百万条数据
    size_t thread_msg_count = msg_count / thread_count;
    for (int i = 0; i < thread_count; i++)
    {
        threads.emplace_back([&, i]()
                             {
            // 4. 线程内部进行开始计时
            auto start = std::chrono::high_resolution_clock::now();
            // 5. 进行循环写日志的操作
            for(int i = 0; i<thread_msg_count; i++)
            {
                logger->Fatal("%s", msg.c_str());
            }
            // 6. 线程内部结束计时，并打印出一个线程耗费的时间
            auto end = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> cost = end-start;
            std::cout << "线程" << i << " 耗时为：" << cost.count() << "s" << std::endl;
            cost_array[i] = cost.count(); });
    }
    for (int i = 0; i < thread_count; i++)
        threads[i].join();
    // 7. 计算总耗时
    // 对于多个线程来说，总耗时应该是耗时最长的线程消耗的时间
    auto costtime = cost_array[0];
    for (int i = 0; i < thread_count; i++)
        costtime = std::max(costtime, cost_array[i]);
    // 8. 进行效率的打印操作
    std::cout << "一共有 " << thread_count << " 个线程执行日志打印操作\n";
    std::cout << "需要输出 " << msg_count << " 条数据\n";
    std::cout << "没条数据的长度为：" << msg_len << std::endl;
    std::cout << "总耗时为：" << costtime << std::endl;
    // 8.1 每秒输出量(每秒输出多少条日志) = 日志数量/总耗时
    std::cout << "每秒输出量(多少条日志/s)为：" << msg_count / costtime << "/s" << std::endl;
    // 8.2 每秒输出大小(每秒输出多大日志) = 日志数量*单条日志大小/总耗时*1024(KB)
    std::cout << "每秒输出大小(kb/s)为：" << (msg_count * msg_len) / (costtime * 1024) << "kb\n";
}

int main()
{
    // 1. 获取到一个日志器构造者对象 -- 传入GlobalLoggerBuilder
    LogModule::LoggerBuilder::ptr builder = std::make_shared<LogModule::GlobalLoggerBuilder>();
    // 2. 初始化日志器
    builder->BuildLoggerLevel(LogModule::LogLevel::Level::DEBUG);
    builder->BuildLoggerName("bench-test");
    builder->BuildLoggerFormatter("%m%n");
    // 测试 -- 只向一个文件中打印
    builder->BuildSink<LogModule::FileLogSink>("./log/log.txt");
    builder->BulidLoggerType(LogModule::LoggerType::LOGGER_SYNC); // 同步/异步
    builder->BuildSetAsyncUnsafe();                                // 安全/不安全
    // 3. 构建出一个日志对象
    builder->build();

    // 1. logger_name：日志器名称
    // 2. thread_count：线程数量
    // 3. msg_count：打印的信息数量
    // 4. msg_len：打印的信息长度
    Bench("bench-test", 1, 1000000, 100);
    return 0;
}